from datetime import datetime
from models import db
import bcrypt

class User(db.Model):
    """用户模型"""
    __tablename__ = 'users'
    
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(50), unique=True, nullable=False)
    password = db.Column(db.String(255), nullable=False)
    email = db.Column(db.String(100), unique=True, nullable=False)
    phone = db.Column(db.String(20))
    avatar = db.Column(db.String(255))
    nickname = db.Column(db.String(50))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    last_login = db.Column(db.DateTime)
    status = db.Column(db.Boolean, default=True)  # 1: 活跃, 0: 禁用
    
    # 关系
    rooms = db.relationship('Room', backref='user', lazy=True, cascade='all, delete-orphan')
    devices = db.relationship('Device', backref='user', lazy=True, cascade='all, delete-orphan')
    scenes = db.relationship('Scene', backref='user', lazy=True, cascade='all, delete-orphan')
    user_settings = db.relationship('UserSettings', backref='user', uselist=False, cascade='all, delete-orphan')
    notification_settings = db.relationship('NotificationSettings', backref='user', uselist=False, cascade='all, delete-orphan')
    login_logs = db.relationship('LoginLog', backref='user', lazy=True, cascade='all, delete-orphan')
    
    def set_password(self, password):
        """设置密码"""
        self.password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
    
    def check_password(self, password):
        """验证密码"""
        return bcrypt.checkpw(password.encode('utf-8'), self.password.encode('utf-8'))
    
    def to_dict(self):
        """转换为字典"""
        return {
            'id': self.id,
            'username': self.username,
            'email': self.email,
            'phone': self.phone,
            'avatar': self.avatar,
            'nickname': self.nickname,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'last_login': self.last_login.isoformat() if self.last_login else None,
            'status': self.status
        }

class Role(db.Model):
    """角色模型"""
    __tablename__ = 'roles'
    
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), unique=True, nullable=False)
    description = db.Column(db.String(255))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

class UserRole(db.Model):
    """用户角色关联模型"""
    __tablename__ = 'user_roles'
    
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'), primary_key=True)

class Room(db.Model):
    """房间模型"""
    __tablename__ = 'rooms'
    
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)
    icon = db.Column(db.String(50), nullable=False)
    description = db.Column(db.String(255))
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关系
    devices = db.relationship('Device', backref='room', lazy=True)
    
    def to_dict(self):
        """转换为字典"""
        return {
            'id': self.id,
            'name': self.name,
            'icon': self.icon,
            'description': self.description,
            'user_id': self.user_id,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'device_count': len(self.devices) if self.devices else 0
        }

class DeviceType(db.Model):
    """设备类型模型"""
    __tablename__ = 'device_types'
    
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), unique=True, nullable=False)
    icon = db.Column(db.String(50))
    description = db.Column(db.String(255))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    
    # 关系
    devices = db.relationship('Device', backref='device_type', lazy=True)

class Device(db.Model):
    """设备模型"""
    __tablename__ = 'devices'
    
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    type_id = db.Column(db.Integer, db.ForeignKey('device_types.id'), nullable=False)
    room_id = db.Column(db.Integer, db.ForeignKey('rooms.id'))
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    status = db.Column(db.Boolean, default=False)  # 0: 关闭, 1: 开启
    online = db.Column(db.Boolean, default=True)   # 0: 离线, 1: 在线
    ip_address = db.Column(db.String(50))
    mac_address = db.Column(db.String(50))
    firmware_version = db.Column(db.String(50))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    last_active = db.Column(db.DateTime)
    
    # 关系
    properties = db.relationship('DeviceProperty', backref='device', lazy=True, cascade='all, delete-orphan')
    
    def to_dict(self):
        """转换为字典"""
        # 获取设备属性
        properties = {}
        for prop in self.properties:
            properties[prop.property_key] = prop.property_value
            
        return {
            'id': self.id,
            'name': self.name,
            'type': self.device_type.name if self.device_type else 'Unknown',
            'type_icon': self.device_type.icon if self.device_type else 'Device',
            'room': self.room.name if self.room else 'Unknown',
            'room_id': self.room.id if self.room else None, # 添加 room_id
            'room_icon': self.room.icon if self.room else 'Home',
            'status': self.status,
            'online': self.online,
            'ip_address': self.ip_address,
            'mac_address': self.mac_address,
            'firmware_version': self.firmware_version,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None,
            'last_active': self.last_active.isoformat() if self.last_active else None,
            'properties': properties
        }

class DeviceProperty(db.Model):
    """设备属性模型"""
    __tablename__ = 'device_properties'
    
    id = db.Column(db.Integer, primary_key=True)
    device_id = db.Column(db.Integer, db.ForeignKey('devices.id'), nullable=False)
    property_key = db.Column(db.String(50), nullable=False)
    property_value = db.Column(db.String(255))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    __table_args__ = (db.UniqueConstraint('device_id', 'property_key'),)

class Scene(db.Model):
    """场景模型"""
    __tablename__ = 'scenes'
    
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    icon = db.Column(db.String(50), nullable=False)
    description = db.Column(db.Text) # 添加 description 字段
    actions = db.Column(db.JSON) # 添加 actions 字段，假设为 JSON 类型
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    is_active = db.Column(db.Boolean, default=False) # 修改为 is_active，并与路由层一致，默认为 False
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    # 关系
    scene_devices = db.relationship('SceneDevice', backref='scene', lazy=True, cascade='all, delete-orphan')
    
    def to_dict(self):
        """转换为字典"""
        return {
            'id': self.id,
            'name': self.name,
            'icon': self.icon,
            'description': self.description,
            'actions': self.actions,
            'is_active': self.is_active, # 修改为 is_active
            'user_id': self.user_id, # 添加 user_id
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'updated_at': self.updated_at.isoformat() if self.updated_at else None, # 添加 updated_at
            'device_count': len(self.scene_devices) if self.scene_devices else 0 # 场景设备关联可能需要调整
        }

class SceneDevice(db.Model):
    """场景设备关联模型"""
    __tablename__ = 'scene_devices'
    
    id = db.Column(db.Integer, primary_key=True)
    scene_id = db.Column(db.Integer, db.ForeignKey('scenes.id'), nullable=False)
    device_id = db.Column(db.Integer, db.ForeignKey('devices.id'), nullable=False)
    target_status = db.Column(db.Boolean, nullable=False)
    properties = db.Column(db.Text)  # JSON字符串
    execution_order = db.Column(db.Integer, default=0)
    
    # 关系
    device = db.relationship('Device', backref='scene_devices')

class DeviceLog(db.Model):
    """设备日志模型"""
    __tablename__ = 'device_logs'
    
    id = db.Column(db.Integer, primary_key=True)
    device_id = db.Column(db.Integer, db.ForeignKey('devices.id'), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    action = db.Column(db.String(50), nullable=False)
    status_before = db.Column(db.String(255))
    status_after = db.Column(db.String(255))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    ip_address = db.Column(db.String(50))
    source = db.Column(db.Enum('user', 'system', 'schedule', 'scene'), nullable=False)
    
    # 关系
    device = db.relationship('Device')
    user = db.relationship('User')

class Notification(db.Model):
    """通知模型"""
    __tablename__ = 'notifications'
    
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    title = db.Column(db.String(100), nullable=False)
    content = db.Column(db.Text, nullable=False)
    type = db.Column(db.Enum('system', 'alert', 'info'), nullable=False)
    is_read = db.Column(db.Boolean, default=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    
    # 关系
    user = db.relationship('User')

class UserSettings(db.Model):
    """用户系统设置模型"""
    __tablename__ = 'user_settings'
    
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, unique=True)
    theme = db.Column(db.Enum('light', 'dark', 'auto'), default='light')
    language = db.Column(db.String(10), default='zh-CN')
    timezone = db.Column(db.String(50), default='Asia/Shanghai')
    auto_update = db.Column(db.Boolean, default=True)
    two_factor_enabled = db.Column(db.Boolean, default=False)
    two_factor_secret = db.Column(db.String(255))
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    def to_dict(self):
        """转换为字典"""
        return {
            'theme': self.theme,
            'language': self.language,
            'timezone': self.timezone,
            'auto_update': self.auto_update,
            'two_factor_enabled': self.two_factor_enabled
        }

class NotificationSettings(db.Model):
    """用户通知设置模型"""
    __tablename__ = 'notification_settings'
    
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, unique=True)
    device_offline = db.Column(db.Boolean, default=True)
    device_abnormal = db.Column(db.Boolean, default=True)
    energy_abnormal = db.Column(db.Boolean, default=True)
    scene_execution = db.Column(db.Boolean, default=False)
    weekly_report = db.Column(db.Boolean, default=True)
    system_update = db.Column(db.Boolean, default=True)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
    
    def to_dict(self):
        """转换为字典"""
        return {
            'device_offline': self.device_offline,
            'device_abnormal': self.device_abnormal,
            'energy_abnormal': self.energy_abnormal,
            'scene_execution': self.scene_execution,
            'weekly_report': self.weekly_report,
            'system_update': self.system_update
        }

class LoginLog(db.Model):
    """用户登录记录模型"""
    __tablename__ = 'login_logs'
    
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    ip_address = db.Column(db.String(50), nullable=False)
    user_agent = db.Column(db.Text)
    location = db.Column(db.String(100))
    device_info = db.Column(db.String(255))
    login_time = db.Column(db.DateTime, default=datetime.utcnow)
    logout_time = db.Column(db.DateTime)
    is_success = db.Column(db.Boolean, default=True)
    
    def to_dict(self):
        """转换为字典"""
        return {
            'id': self.id,
            'ip': self.ip_address,
            'location': self.location or '未知',
            'device': self.device_info or '未知设备',
            'time': self.login_time.strftime('%Y-%m-%d %H:%M:%S') if self.login_time else None,
            'is_success': self.is_success
        }
